﻿using CNative.EntityBuilder.CreateText;
using CNative.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CNative.EntityBuilder
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }
        private KMenuTabControl tabCode;
        private string sqlLink = "BaseDb";
        private string dbName = "", tableName = "", tableNameDes = "";
        #region FrmMain_Load
        private void FrmMain_Load(object sender, EventArgs e)
        {
            //读取配置文件中的信息
            Config.loadConfigInfo();
            init();
        }
        #region 初始化数据
        public void init()
        {
            this.tabCode = new KMenuTabControl(); 
            this.tabCode.SuspendLayout();
            this.tabCode.Appearance = TabAppearance.Buttons;
            this.tabCode.Dock = DockStyle.Fill;
            this.tabCode.DrawMode = TabDrawMode.OwnerDrawFixed;
            this.tabCode.HotTrack = true;
            this.tabCode.ImageList = this.imageList1;
            this.tabCode.SizeMode = TabSizeMode.FillToRight;
            this.panel1.Controls.Add(this.tabCode);
            this.tabCode.ResumeLayout(false);

            tabCode.DrawMode = TabDrawMode.OwnerDrawFixed;
            //tabCode.DrawItem += tabCode_DrawItem;
            //tabCode.MouseDown += tabCode_MouseDown;
            tabCode.TabPages.Clear();

            //treeview显示checkbox
            treeView.CheckBoxes = true;
            this.treeView.AfterCheck += new TreeViewEventHandler(treeView1_AfterCheck);
            //TreeView 只部分节点显示  CheckBox
            this.treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
            this.treeView.DrawNode += new DrawTreeNodeEventHandler(tree_DrawNode);

            //获取默认的命名空间名称
            this.txtNameSpace.Text = Config.NameSpace;
            this.txtCreator1.Text = Config.Creator;
            bindtsCmbLink();
            try
            {
                this.chkTable.Checked = Convert.ToBoolean(Config.IniReadValue("chkTable", chkTable.Checked.ToString()));
                this.chkCol.Checked = Convert.ToBoolean(Config.IniReadValue("chkCol", chkCol.Checked.ToString()));
                this.chkguid.Checked = Convert.ToBoolean(Config.IniReadValue("chkguid", chkguid.Checked.ToString()));
            }
            catch { }

            this.treeView.Nodes.Clear();
            AddNode(null, "DBName");
        }
        #endregion
        #endregion

        #region tree_DrawNode
        void tree_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            if (e.Node.Level > 1)
            {
                HideCheckBox(e.Node);
                e.DrawDefault = true;
            }
            else
            {
                e.Graphics.DrawString(e.Node.Text, e.Node.TreeView.Font,
                   Brushes.Black, e.Node.Bounds.X, e.Node.Bounds.Y);
            }
        }
        private void HideCheckBox(TreeNode node)
        {
            TVITEM tvi = new TVITEM();
            tvi.hItem = node.Handle;
            tvi.mask = TVIF_STATE;
            tvi.stateMask = TVIS_STATEIMAGEMASK;
            tvi.state = 0;
            IntPtr lparam = Marshal.AllocHGlobal(Marshal.SizeOf(tvi));
            Marshal.StructureToPtr(tvi, lparam, false);
            SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, lparam);
        }
        // constants used to hide a checkbox
        public const int TVIF_STATE = 0x8;
        public const int TVIS_STATEIMAGEMASK = 0xF000;
        public const int TV_FIRST = 0x1100;
        public const int TVM_SETITEM = TV_FIRST + 63;

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        // struct used to set node properties
        public struct TVITEM
        {
            public int mask;
            public IntPtr hItem;
            public int state;
            public int stateMask;
            [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]
            public String lpszText;
            public int cchTextMax;
            public int iImage;
            public int iSelectedImage;
            public int cChildren;
            public IntPtr lParam;
        }
        #endregion
        #region treeView1_AfterCheck
        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {

            if (e.Action == TreeViewAction.ByMouse)
            {
                if (e.Node.Checked)
                {
                    //取消节点选中状态之后，取消所有父节点的选中状态
                    setChildNodeCheckedState(e.Node, true);
                }
                else
                {
                    //取消节点选中状态之后，取消所有父节点的选中状态
                    setChildNodeCheckedState(e.Node, false);
                    //如果节点存在父节点，取消父节点的选中状态
                    if (e.Node.Parent != null)
                    {
                        setParentNodeCheckedState(e.Node, false);
                    }
                }
            }
        }
        //取消节点选中状态之后，取消所有父节点的选中状态
        private void setParentNodeCheckedState(TreeNode currNode, bool state)
        {
            TreeNode parentNode = currNode.Parent;

            parentNode.Checked = state;
            if (currNode.Parent.Parent != null)
            {
                setParentNodeCheckedState(currNode.Parent, state);
            }
        }
        //选中节点之后，选中节点的所有子节点
        private void setChildNodeCheckedState(TreeNode currNode, bool state)
        {
            TreeNodeCollection nodes = currNode.Nodes;
            if (nodes.Count > 0)
                foreach (TreeNode tn in nodes)
                {
                    tn.Checked = state;
                    setChildNodeCheckedState(tn, state);
                }
        }

        /// <summary>
        /// 查询TreeView下节点被checked的数目
        /// </summary>
        /// <param name="treev"></param>
        /// <returns></returns>
        private IEnumerable<Tuple<string, string,string>> GetTreeViewNodeChecked(TreeView treev)
        {
            var lst = new List<Tuple<string, string, string>>();
            foreach (TreeNode item in treev.Nodes)
            {
                var seles = GetNodeChecked(item);
                if (seles.Any()) lst.AddRange(seles);
                //foreach (var tuple in GetNodeChecked(item))
                //    yield return tuple;
            }
            return lst;
        }
        /// <summary>
        /// 查询treeNode节点下有多少节点被选中（递归实现，不受级数限制）
        /// </summary>
        /// <param name="tv"></param>
        /// <returns></returns>
        private IEnumerable<Tuple<string,string,string>> GetNodeChecked(TreeNode tv)
        {
            var lst = new List<Tuple<string, string, string>>();
            if (tv.Checked && tv.Level == 1)
            {
                lst.Add(getNodeChecked(tv));
            }
            else if (tv.Level == 0)
            {
                foreach (TreeNode item in tv.Nodes)
                {
                    if (item.Checked)
                    {
                        lst.Add(getNodeChecked(item));
                    }
                }
            }
            return lst;
        }
        private Tuple<string, string, string> getNodeChecked(TreeNode tv, bool isSelect = false)
        {
            if ((isSelect || tv.Checked) && tv.Level == 1)
            {
                var key = tv.Tag.ToString();
                var text = tv.Text;
                if (key == "Tables" || key == "Views")
                {
                    var dbName = tv.Parent.Text;
                    var tableName = text;
                    if (text.EndsWith(")") && text.IndexOf("(") > 0)
                        tableName = text.Substring(0, text.IndexOf("("));

                    return Tuple.Create(dbName, tableName, text);
                }
            }
            return null;
        }
        #endregion

        #region AddNode
        private void AddNode(TreeNode ParentNode, string key, string dbName = "", string tableName = "")
        {
            try
            {
                //得到数据库中的所有库
                List<string> objs = new List<string>();
                int ImageIndex = 7, SelectedImageIndex = 8;
                if (key == "DBName")
                {
                    objs = Config.dBMetadata.GetAllDatabases();
                    ImageIndex = 7;
                    SelectedImageIndex = 8;
                }
                else if (key == "Tables")
                {
                    objs = Config.dBMetadata.GetAllTables(dbName);
                    ImageIndex = 11;
                    SelectedImageIndex = 16;
                }
                else if (key == "Views")
                {
                    objs = Config.dBMetadata.GetAllViews(dbName);
                    ImageIndex = 15;
                    SelectedImageIndex = 12;
                }
                else if (key == "AllColumns")
                {
                    objs = Config.dBMetadata.GetAllColumns(tableName, dbName).Select(s => s.ToString()).ToList();
                    ImageIndex = 11;
                    SelectedImageIndex = 11;
                }
                //添加根节点
                if (objs != null && objs.Count > 0)
                {
                    objs.ForEach(x =>
                    {
                        var rnode = new TreeNode() { Text = x };
                        rnode.Tag = key;
                        rnode.ImageIndex = ImageIndex;
                        rnode.SelectedImageIndex = SelectedImageIndex;
                        //rnode.ContextMenuStrip = cmsNode;
                        if (ParentNode == null)
                            treeView.Nodes.Add(rnode);
                        else
                            ParentNode.Nodes.Add(rnode);
                    });
                }
            }
            catch (Exception ex)
            { 
                MessageBox.Show(ex.GetExceptionMessage());
            }
        }
        private void treeView_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                var key = treeView.SelectedNode.Tag.ToString();
                var text = tableNameDes = treeView.SelectedNode.Text;
                if (key == "DBName")
                {
                    dbName = text;
                    if (treeView.SelectedNode.Nodes.Count == 0)
                    {
                        AddNode(treeView.SelectedNode, "Tables", text);
                        AddNode(treeView.SelectedNode, "Views", text);
                        treeView.SelectedNode.Expand();
                    }
                }
                else if (key == "Tables" || key == "Views")
                {
                    dbName = treeView.SelectedNode.Parent.Text;
                    if (text.EndsWith(")") && text.IndexOf("(") > 0)
                        tableName = text.Substring(0, text.IndexOf("("));
                    else
                        tableName = text;
                    this.txtClassName.Text = Config.EntitySuffix + ClearSpecialChars(tableName);
                    if (treeView.SelectedNode.Nodes.Count == 0)
                    {
                        if (treeView.SelectedNode.Parent != null)
                        {
                            AddNode(treeView.SelectedNode, "AllColumns", treeView.SelectedNode.Parent.Text, tableName);
                            treeView.SelectedNode.Expand();
                        }
                    }
                    var fileName = Config.EntitySuffix + ClearSpecialChars(tableName) + ".cs";
                    tabControlCheckHave(tabCode, fileName);
                }
            }
            catch (Exception ex)
            { //MessageBox.Show(ex.ToString());
            }
        }

        //清除特殊字符
        private string ClearSpecialChars(string oldStr)
        {
            string reStr = oldStr;
            if (Config.IsClearSpecialChars)
            {
                reStr = Config.GetEntityNameByTableName(reStr);
            }
            return reStr;
        }
        #endregion
        #region 节点查找
        /// <summary>
        /// 遍历树节点，并将节点存入List<TreeNode>集合中
        /// </summary>
        /// <param name="node"></param>
        /// <param name="nodeList"></param>
        private void GetAllNodes(TreeNodeCollection nodeCollection, List<TreeNode> nodeList)
        {
            foreach (TreeNode itemNode in nodeCollection)
            {
                nodeList.Add(itemNode);
                GetAllNodes(itemNode.Nodes, nodeList);
            }
        }

        /// <summary>
        /// 模糊匹配(向下查找)
        /// </summary>
        /// <param name="inputText"></param>
        /// <returns></returns>
        private int FindNodePartDown(List<TreeNode> nodeList, string inputText, int startCount)
        {
            if (nodeList?.Count > 0)
            {
                if (startCount < 0)
                    startCount = 0;
                for (int i = startCount; i < nodeList.Count; i++)
                {
                    if (nodeList[i].Text.Contains(inputText, StringComparison.OrdinalIgnoreCase))
                    {
                        return i;
                    }
                }
            }
            return -1;
        }

        /// <summary>
        /// 模糊匹配(向上查找)
        /// </summary>
        /// <param name="inputText"></param>
        /// <returns></returns>
        private int FindNodePartUp(List<TreeNode> nodeList, string inputText, int startCount)
        {
            if (nodeList?.Count > 0)
            {
                if (startCount == 0)
                    startCount = nodeList.Count - 1;
                for (int i = startCount; i >= 0; i--)
                {
                    if (nodeList[i].Text.Contains(inputText, StringComparison.OrdinalIgnoreCase))
                    {
                        return i;
                    }
                }
            }
            return -2;
        }
        /// <summary>
        /// 全字匹配查找(向下查找)
        /// </summary>
        /// <param name="inputText">查找的内容</param>
        /// <param name="startCount">起始位置</param>
        /// <returns></returns>
        private int FindNodeAllDown(List<TreeNode> nodeList, string inputText, int startCount)
        {
            if (nodeList?.Count > 0)
            {
                if (startCount < 0)
                    startCount = 0;
                for (int i = startCount; i < nodeList.Count; i++)
                {
                    if (nodeList[i].Text.StartsWith(inputText, StringComparison.OrdinalIgnoreCase))
                    {
                        return i;
                    }
                }
            }
            return -1;
        }
        /// <summary>
        /// 全字匹配查找(向上查找)
        /// </summary>
        /// <param name="inputText">查找的内容</param>
        /// <param name="startCount">起始位置</param>
        /// <returns></returns>
        private int FindNodeAllUp(List<TreeNode> nodeList,string inputText, int startCount)
        {
            if (nodeList?.Count > 0)
            {
                if (startCount == 0)
                    startCount = nodeList.Count - 1;
                for (int i = startCount; i >= 0; i--)
                {
                    if (nodeList[i].Text.StartsWith(inputText, StringComparison.OrdinalIgnoreCase))
                    {
                        return i;
                    }
                }
            }
            return -2;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="inputText">输入框的值</param>
        /// <param name="usCheckWord">判断是否全字匹配</param>
        /// <param name="isUp">是向上查找</param>
        private void btnQueryNext(string inputText, bool usCheckWord, bool isUp)
        {
            if (inputText.IsNullOrEmpty()) return;

            var lastFindCount = -1;
            var nodeList = new List<TreeNode>();
            GetAllNodes(treeView.Nodes, nodeList);
            if (treeView.SelectedNode != null)
            {
                var lastFindString = treeView.SelectedNode.Text;
                lastFindCount = FindNodeAllUp(nodeList, lastFindString, 0);
            }
            if (usCheckWord)//判断是否全字匹配
            {
                if (isUp == true)
                {
                    lastFindCount = FindNodeAllUp(nodeList, inputText, lastFindCount - 1);  //相同则从下一个节点开始查找
                }
                else
                {
                    lastFindCount = FindNodeAllDown(nodeList, inputText, lastFindCount + 1);  //相同则从下一个节点开始查找
                }
            }
            else
            {
                if (isUp == true)
                {
                    lastFindCount = FindNodePartUp(nodeList, inputText, lastFindCount - 1);
                }
                else
                {
                    lastFindCount = FindNodePartDown(nodeList, inputText, lastFindCount + 1);
                }
            }
            if (lastFindCount == -1)//判断是否找到节点
            {
                MessageBox.Show("查找到尾部，未找到指定的节点！");
                this.Focus();
                return;
            }
            else if (lastFindCount == -2)        //判断是否找到节点
            {
                MessageBox.Show("查找到顶部，未找到指定的节点！");
                this.Focus();
                return;
            }
            var node = nodeList[lastFindCount];
            treeView.SelectedNode = node;        //选中查找到的节点
            treeView.Focus();
        }
        private void btnNext_Click(object sender, EventArgs e)
        {
            btnQueryNext(txtSearch.Text, false, false);
        }
        private void btnUPF_Click(object sender, EventArgs e)
        {
            btnQueryNext(txtSearch.Text, false, true);
        }

        private void txtSearch_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter) btnNext.PerformClick();
        }
        #endregion

        private void btnBuild_Click(object sender, EventArgs e)
        {
            #region 输入验证
            //if (this.dbName.IsNullOrEmpty() || this.tableName.IsNullOrEmpty())
            //{
            //    MessageBox.Show("没有可以生成的表！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //    return;
            //}
            if (this.txtNameSpace.Text.Trim() == "")
            {
                MessageBox.Show("请输入命名空间名称！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //if (!Regex.IsMatch(this.txtNameSpace.Text, "[a-zA-Z][a-zA-Z.]*[a-zA-Z]$"))
            //{
            //    MessageBox.Show("输入的命名空间名称不正确！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //    return;
            //}
            //if (this.txtClassName.Text.Trim() == "")
            //{
            //    MessageBox.Show("请输入类名！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //    return;
            //}
            //if (string.IsNullOrEmpty(this.txtClassName.Text))//!Regex.IsMatch(this.txtClassName.Text, @"^[A-Z]\w*[a-zA-Z]$")
            //{
            //    MessageBox.Show("输入的类名不正确！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //    return;
            //}
            #endregion
            #region 生成代码

            string creator = this.txtCreator1.Text.Trim();
            string nameSpace = this.txtNameSpace.Text.Trim();
            Config.NameSpace = nameSpace;
            Config.Creator = creator;

            //CreateModelCode();
            var seles = GetTreeViewNodeChecked(this.treeView);
            if (!seles.Any())
            {
                var f = getNodeChecked(treeView.SelectedNode,true);
                if (f != null)
                {
                    seles = new List<Tuple<string, string, string>> { f };
                }
                else
                {
                    MessageBox.Show("没有可以生成的表！", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            seles?.ForEach(f =>
            {
                var dbName = f.Item1;
                var tableName = f.Item2;
                var tableNameDes= f.Item3;
                var byName = Config.EntitySuffix + ClearSpecialChars(tableName);
                var fileName = byName + ".cs";

                if (!tabControlCheckHave(tabCode, fileName))
                {
                    var codeText = Config.CreateModel.Ganarate(nameSpace, dbName, tableName, tableNameDes, byName, this.chkTable.Checked, this.chkCol.Checked, this.chkguid.Checked);
                    Add_TabPage(fileName, new ucCodeView() { CodeText = codeText });
                }
            });
            #endregion
            #region 修改配置文件

            Config.NameSpace = nameSpace;
            Config.Creator = creator;

            Config.saveConfigInfo();

            Config.IniWriteValue("chkTable", chkTable.Checked.ToString());
            Config.IniWriteValue("chkCol", chkCol.Checked.ToString());
            Config.IniWriteValue("chkguid", chkguid.Checked.ToString());
            #endregion
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            #region 输入验证

            //if (txtModelCode.Text.Trim() == "")
            //{
            //    MessageBox.Show("请先生成代码！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //    return;
            //}

            #endregion
            #region 保存
            var seles = GetTreeViewNodeChecked(this.treeView);
            if (!seles.Any())
            {
                var f = getNodeChecked(treeView.SelectedNode, true);
                if (f != null)
                {
                    seles = new List<Tuple<string, string, string>> { f };
                }
                else
                {
                    MessageBox.Show("没有可以生成的表！", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }

            string creator = this.txtCreator1.Text.Trim();
            string nameSpace = this.txtNameSpace.Text.Trim();
            FolderBrowserDialog browserDialog = new FolderBrowserDialog();
            browserDialog.SelectedPath = Config.FilePath;
            //browserDialog.RootFolder = Environment.SpecialFolder.Startup;
            if (browserDialog.ShowDialog(this) == DialogResult.OK)
            {
                FileDataHelper.CreateDirectory(browserDialog.SelectedPath);
                seles?.ForEach(f =>
                {
                    var dbName = f.Item1;
                    var tableName = f.Item2;
                    var tableNameDes = f.Item3;
                    var byName = Config.EntitySuffix + ClearSpecialChars(tableName);
                    var fileName = System.IO.Path.Combine(browserDialog.SelectedPath, byName + ".cs");

                    var codeText = Config.CreateModel.Ganarate(nameSpace, dbName, tableName, tableNameDes, byName, this.chkTable.Checked, this.chkCol.Checked, this.chkguid.Checked);
                    if (codeText.IsNotNullOrEmpty())
                        FileDataHelper.CreateFile(fileName, codeText, true, Encoding.UTF8);
                });
                MessageBox.Show("保存成功！", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Config.FilePath = browserDialog.SelectedPath;
                FileDataHelper.OpenDirectory(Config.FilePath);
            }
            #endregion
            #region 修改配置文件

            Config.NameSpace = nameSpace;
            Config.Creator = creator;

            Config.saveConfigInfo();

            #endregion
            #region 设置默认保存目录

            //SaveFileDialog openFileDialog = new SaveFileDialog();

            //openFileDialog.InitialDirectory = Config.FilePath;
            //openFileDialog.Filter = "代码文件(*.cs)|*.cs";
            //openFileDialog.DefaultExt = "cs";
            //#endregion

            //#region 设置默认保存名称

            //openFileDialog.FileName = this.txtClassName.Text.Trim();

            //#endregion

            //#region 保存文件

            //if (openFileDialog.ShowDialog(this) == DialogResult.OK)
            //{
            //    Config.FilePath = System.IO.Path.GetDirectoryName(openFileDialog.FileName);
            //    string FileName = openFileDialog.FileName;
            //    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(FileName, false, Encoding.Default))
            //    {
            //        //if (this.tabCode.SelectedTab == this.tpModel)
            //        //{
            //        //    sw.Write(txtModelCode.Text);
            //        //}
            //    }
            //}

            #endregion
        }

        #region tsCmbLink_SelectedIndexChanged
        private void tsCmbLink_SelectedIndexChanged(object sender, EventArgs e)
        {
            Config.setDBMetadata(tsCmbLink.Text);
            this.treeView.Nodes.Clear();
            AddNode(null, "DBName");
            sqlLink = tsCmbLink.Text;
            Config.IniWriteValue("defaultConnectionString", sqlLink);
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            //txtModelCode.Text = txtModelCode.Text.ToHzPY();
        }

        private void bindtsCmbLink()
        {
            try
            {
                var cls = CNative.Utilities.ConfigurationHelper.ConnectionStrings;
                var defaultConnectionString = Config.IniReadValue("defaultConnectionString", sqlLink).Trim().ToLower();
                tsCmbLink.Items.Clear();
                foreach (var cl in cls)
                {
                    tsCmbLink.Items.Add(cl.Key);
                    if (!string.IsNullOrEmpty(defaultConnectionString) && cl.Key.ToLower() == defaultConnectionString)
                        tsCmbLink.Text = cl.Key;
                }
                if (tsCmbLink.Items.Count == 0)
                    MessageBox.Show("未配置 ConnectionStrings", "错误");
            }
            catch { }
        }
        #endregion

        #region Add_TabPage
        private void Add_TabPage(string str, Control control)
        {
            if (tabControlCheckHave(this.tabCode, str))
            {
                return;
            }
            else
            {
                tabCode.TabPages.Add(str);
                tabCode.SelectTab(tabCode.TabPages.Count - 1);

                control.Dock = DockStyle.Fill;
                control.Parent = tabCode.SelectedTab;
            }
        }

        private bool tabControlCheckHave(TabControl tab, String tabName)
        {
            for (int i = 0; i < tab.TabCount; i++)
            {
                if (tab.TabPages[i].Text == tabName)
                {
                    tab.SelectedIndex = i;
                    return true;
                }
            }
            return false;
        }
        private void tabCode_DrawItem(object sender, DrawItemEventArgs e)
        {
            /*如果将 DrawMode 属性设置为 OwnerDrawFixed， 
            则每当 TabControl 需要绘制它的一个选项卡时，它就会引发 DrawItem 事件*/
            try
            {
                if(this.tabCode.TabPages[e.Index]== this.tabCode.SelectedTab)
                {
                    this.tabCode.TabPages[e.Index].Font= new Font("微软雅黑", 10.5F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(134)));
                }
                else
                {
                    this.tabCode.TabPages[e.Index].Font = new Font("微软雅黑", 10.5F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
                }
                this.tabCode.TabPages[e.Index].BackColor = Color.LightBlue;
                Rectangle tabRect = this.tabCode.GetTabRect(e.Index);
                e.Graphics.DrawString(this.tabCode.TabPages[e.Index].Text, this.Font, SystemBrushes.ControlText, (float)(tabRect.X + 2), (float)(tabRect.Y + 2));
                using (Pen pen = new Pen(Color.White))
                {
                    tabRect.Offset(tabRect.Width - 15, 2);
                    tabRect.Width = 15;
                    tabRect.Height = 15;
                    e.Graphics.DrawRectangle(pen, tabRect);
                }
                Color color = (e.State == DrawItemState.Selected) ? Color.LightBlue : Color.White;
                using (Brush brush = new SolidBrush(color))
                {
                    e.Graphics.FillRectangle(brush, tabRect);
                }
                using (Pen pen2 = new Pen(Color.Red))
                {
                    Point point = new Point(tabRect.X + 3, tabRect.Y + 3);
                    Point point2 = new Point((tabRect.X + tabRect.Width) - 3, (tabRect.Y + tabRect.Height) - 3);
                    e.Graphics.DrawLine(pen2, point, point2);
                    Point point3 = new Point(tabRect.X + 3, (tabRect.Y + tabRect.Height) - 3);
                    Point point4 = new Point((tabRect.X + tabRect.Width) - 3, tabRect.Y + 3);
                    e.Graphics.DrawLine(pen2, point3, point4);
                }
                e.Graphics.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void tabCode_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int x = e.X;
                int y = e.Y;

                Rectangle tabRect = this.tabCode.GetTabRect(this.tabCode.SelectedIndex);
                tabRect.Offset(tabRect.Width - 0x12, 2);
                tabRect.Width = 15;
                tabRect.Height = 15;
                if ((((x > tabRect.X) && (x < tabRect.Right)) && (y > tabRect.Y)) && (y < tabRect.Bottom))
                {
                    this.tabCode.TabPages.Remove(this.tabCode.SelectedTab);
                }
            }
        }
        #endregion

        #region FrmMain_FormClosing
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("是否要退出实体类型生成工具？", "退出", MessageBoxButtons.YesNo) != DialogResult.Yes)
            {
                e.Cancel = true;
            }
        }
        #endregion
    }
}
